package astStatData;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.TypeDeclaration;

public class MapBuilder extends ASTVisitor{
	private ElementMap map;
	private CompilationUnit contentCU;
	private ITypeBinding currentClassBd;
	
	public MapBuilder (ElementMap m, CompilationUnit cu){
		map = m;
		contentCU = cu;
	}

	public boolean visit(ClassInstanceCreation node){
		IMethodBinding b = node.resolveConstructorBinding();
		map.put(b.getKey(), contentCU);
		System.out.println("ClassInstanceCreation: " +
						//	"\t DeclaringClass: "+ b.getDeclaringClass()+
							"\t ConstructorBinding: "+ b.getName()
							+"\t key is :"+b.getKey() +"\n");
		return true;
	}
	
	
	public boolean visit(FieldAccess node){
		IVariableBinding b = node.resolveFieldBinding();
//		ASTNode n = map.get(b.getKey());
		
//		map.put(b.getKey(), contentCU);
		
		System.out.println("FieldAccess" + b.getDeclaringMethod().toString()+" key is :"+b.getKey() +"\n");
		return true;
	}
	
	public boolean visit(MethodInvocation node){
		IMethodBinding b= node.resolveMethodBinding();

		map.put(b.getKey(), contentCU);

		System.out.println( "MethodInvocation: \n" + node.getName()
							+ "\nIMethodBinding: "+b.getName()
							+ "\nkey: "+b.getKey() 
							+ "\nDeclaringClass: " + b.getDeclaringClass().getKey() +"\n" +
							"current class: "+ currentClassBd.getName());
							
		
		return true;
	}
	

	
	public boolean visit(MethodDeclaration node) {
		IMethodBinding b = node.resolveBinding();
		
//		map.put(b.getKey(), ((ASTNode)contentCU) );
		
		System.out.println( "MethodDeclaration: ");
		System.out.println( node.getName() );
		System.out.println( node.getBody() );
		System.out.println( "\nIMethodBinding: "+b.getName()
								+ "\nkey: "+b.getKey() 
								+ "\nDeclaringClass: " +  b.getDeclaringClass().getName() +"\n" +
							    "current class: "+ currentClassBd.getName());
		return true;
	}
	
	public boolean visit(TypeDeclaration node){
		ITypeBinding b = node.resolveBinding();
		currentClassBd = b;
		map.put(b.getKey(), contentCU);
		System.out.println("TypeDeclaration:\n" );
		System.out.println(node.getName());
		System.out.println("TypeBinding: "+ b.getName());
		System.out.println("key: " + b.getKey() );
		System.out.println("==========TypeDeclaration END======");

		
		return true;
	}

	public void endVisit(MethodInvocation node){
//		System.out.println("=============MethodInvocation END=================\n");
	}
	
	public void endVisit(MethodDeclaration node) {
//		System.out.println( "--------------MethodDeclaration END----------------------\n");
	}
	

	public void preVisit(ASTNode node){
		if(node instanceof CompilationUnit){
			System.out.println("--------------------START MabBuild--------------------\n");
		}
	} 

	public void postVisit(ASTNode node){
		if(node instanceof CompilationUnit){
			System.out.println("--------------------END MapBuild--------------------\n");
			map.addCU( contentCU );
		}
	}
}

